# 如果有写者申请写文件，那么在申请之前还在读取文件的读进程可以继续读取，但是如果再有读者申请读取文件，则不能够读取，只有在所有的写者写完之后才可以读取。

import threading
import time

import reader_first as rf

# 用于线程安全的输出
print_lock = threading.Lock()


# 模拟获取当前时间（基于一个开始时间点）
def get_current_time(start):
    return int(time.time() - start)


# 模拟获取从开始到现在的经过时间
def get_elapsed_time(start):
    return get_current_time(start)

Rcount = 0  # 进行的读者队列数量
Wcount = 0  # 进行的写者队列数量
Wmutex = threading.Semaphore(1)  #  对临界资源Wcount的互斥访问
Rmutex = threading.Semaphore(1)  # 对临界资源Rcount的互斥访问
Read = threading.Semaphore(1)  # “读文件”的互斥锁
Write = threading.Semaphore(1)  # “写文件”的互斥锁

def reader(i,sleept,start,start_sleep):
    time.sleep(start_sleep)
    with print_lock:
        print(f'时间点  {get_current_time(start)}  读者-{i} 开始等待阅读')
    Read.acquire()
    Rmutex.acquire()
    global Rcount
    Rcount += 1
    if Rcount == 1:
        Write.acquire()
    Rmutex.release()
    Read.release()
    with print_lock:
        print(f'时间点  {get_current_time(start)}  读者-{i} 正在阅读')
    time.sleep(sleept)
    with print_lock:
        print(f'时间点  {get_current_time(start)}  读者-{i} 完成阅读')
    Rmutex.acquire()
    Rcount -= 1
    if Rcount == 0:
        Write.release()
    Rmutex.release()

def writer(i,sleept,start,start_sleep):
    time.sleep(start_sleep)
    with print_lock:
        print(f'时间点  {get_current_time(start)}  写者-{i} 开始等待写')
    Wmutex.acquire()
    global Wcount
    Wcount += 1
    if Wcount == 1:
        Read.acquire()
    Wmutex.release()
    Write.acquire()
    with print_lock:
        print(f'时间点  {get_current_time(start)}  写者-{i} 正在写')
    time.sleep(sleept)
    with print_lock:
        print(f'时间点  {get_current_time(start)}  写者-{i} 完成写')
    Write.release()
    Wmutex.acquire()
    Wcount -= 1
    if Wcount == 0:
        Read.release()
    Wmutex.release()


if __name__ == '__main__':
    idx = []
    type_list = []
    start_time = []
    continue_time = []
    error_count = 0  # 添加错误计数器

    try:
        with open('in.txt', 'r') as f:
            data = f.readlines()
            for line_num, line in enumerate(data, start=1):
                x = line.strip().split()
                if len(x) < 4:
                    print(f"警告：文件格式错误，第 {line_num} 行缺少必要的字段")
                    error_count += 1
                    continue

                try:
                    idx_value = int(x[0])
                    if idx_value < 0:
                        raise ValueError("第一列必须为非负整数")
                    type_value = x[1]
                    if type_value not in ['R', 'W']:
                        raise ValueError("第二列必须是 'R' 或 'W'")
                    start_time_value = int(x[2])
                    if start_time_value < 0:
                        raise ValueError("第三列必须为非负整数")
                    continue_time_value = int(x[3])
                    if continue_time_value < 0:
                        raise ValueError("第四列必须为非负整数")

                    idx.append(idx_value)
                    type_list.append(type_value)
                    start_time.append(start_time_value)
                    continue_time.append(continue_time_value)
                except ValueError as e:
                    print(f"错误：第 {line_num} 行数据格式错误 - {e}")
                    error_count += 1

        if error_count == 0:  # 如果没有错误行，才继续执行
            start = time.time()
            threads = []
            for i in range(len(type_list)):
                if type_list[i] == 'R':
                    t = threading.Thread(target=rf.reader, args=(idx[i], continue_time[i], start, start_time[i]))
                else:
                    t = threading.Thread(target=rf.writer, args=(idx[i], continue_time[i], start, start_time[i]))
                t.start()
                threads.append(t)

            # 等待所有线程完成
            for t in threads:
                t.join()

            print("所有任务已完成。")
        else:
            print(f"有 {error_count} 行数据格式错误，未启动线程。")

    except FileNotFoundError:
        print("错误：文件 'in.txt' 未找到")
    except Exception as e:
        print(f"发生了一个未预料的错误：{e}")